package com.huawei.chengdu.meetingdemo.view;

import static com.huawei.chengdu.meetingdemo.view.InMeetingFragmentFixed.SURFACE_VIEWID_MAP;

import android.content.Context;
import android.graphics.PixelFormat;
import android.provider.Settings;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageButton;

import com.device.idea.meeting.CallCtrl.model.ConfState;
import com.device.idea.meeting.MultiStream.model.LayoutMode;
import com.huawei.chengdu.meetingdemo.R;
import com.huawei.chengdu.meetingdemo.consts.ConfConst;
import com.huawei.chengdu.meetingdemo.presenter.ConfSdkPresenter;
import com.huawei.chengdu.meetingdemo.presenter.MeetingManager;
import com.huawei.chengdu.meetingdemo.util.LogUtil;

import java.util.function.Consumer;

public class PipWindowView {
    private final Consumer<ConfState> confStateListener = this::handleConfStateChangeNotify;
    public View view;
    private Context mContext;
    public SurfaceView surfaceViewPip;
    private FrameLayout pipWindowLayout;
    private ImageButton pipHideButton;
    private WindowManager windowManager;
    private WindowManager.LayoutParams layoutParams;
    private GestureDetector mGestureDetector;
    private int pipTouchX;
    private int pipTouchY;
    private LayoutMode curLayoutMode;
    private boolean isShowing = false;

    public PipWindowView(Context context) {
        mContext = context;
        initView();
        initListener();
        initLayoutParam();
    }

    private void initView() {
        LayoutInflater layoutInflater = LayoutInflater.from(mContext);
        view = layoutInflater.inflate(R.layout.pip_window_layout, null);
        surfaceViewPip = view.findViewById(R.id.surface_view_pip);
        pipWindowLayout = view.findViewById(R.id.pip_window);
        pipHideButton = view.findViewById(R.id.conf_pip_window_hide);
    }

    private void initListener() {
        MeetingManager.getInstance().addConfStateListener(confStateListener);
        pipWindowLayout.setOnTouchListener(this::pipWindowOnTouch);
        pipHideButton.setOnClickListener(v -> handlePipHideClick());
        mGestureDetector = new GestureDetector(mContext, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onDown(MotionEvent e) {
                return false;
            }

            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
                return false;
            }

            @Override
            public boolean onDoubleTap(MotionEvent e) {
                if (HomeActivity.isInForeground) {
                    ConfSdkPresenter.switchPipLocation(SURFACE_VIEWID_MAP.get(surfaceViewPip.getId()));
                } else {
                    ConfSdkPresenter.backToVideoScreen(SURFACE_VIEWID_MAP.get(surfaceViewPip.getId()));
                }
                return true;
            }
        });
    }

    private void initLayoutParam() {
        windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        layoutParams = new WindowManager.LayoutParams();
        layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
        layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
        layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        layoutParams.format = PixelFormat.RGBA_8888;
    }

    public void show() {
        if (!Settings.canDrawOverlays(mContext)) {
            return;
        }
        if (isShowing) {
            LogUtil.info("Update pip window.");
            windowManager.updateViewLayout(view, layoutParams);
            return;
        }
        LogUtil.info("Begin show pip window.");
        surfaceViewPip.setVisibility(View.VISIBLE);
        windowManager.addView(view, layoutParams);
        isShowing = true;
    }

    public void hide() {
        if (isShowing) {
            surfaceViewPip.setVisibility(View.GONE);
            windowManager.removeViewImmediate(view);
            isShowing = false;
        }
    }

    private void handleConfStateChangeNotify(ConfState confState) {
        if (confState == ConfState.NONE) {
            hide();
        }
    }

    private void handlePipHideClick() {
        if (surfaceViewPip.getVisibility() == View.VISIBLE) {
            surfaceViewPip.setVisibility(View.GONE);
            pipHideButton.setImageResource(R.drawable.button_down_enable);
            ConfSdkPresenter.hideView(SURFACE_VIEWID_MAP.get(surfaceViewPip.getId()), true);
        } else {
            surfaceViewPip.setVisibility(View.VISIBLE);
            pipHideButton.setImageResource(R.drawable.button_up_enable);
            ConfSdkPresenter.hideView(SURFACE_VIEWID_MAP.get(surfaceViewPip.getId()), false);
        }
    }

    private boolean pipWindowOnTouch(View v, MotionEvent event) {
        mGestureDetector.onTouchEvent(event);
        int nowX = (int) event.getRawX();
        int nowY = (int) event.getRawY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                pipTouchX = nowX;
                pipTouchY =nowY;
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                int upX = nowX;
                int upY = nowY;
                handlePipMove(pipTouchX, pipTouchY, upX, upY);
                if (Math.abs(pipTouchX - upX) + Math.abs(pipTouchY - upY) < 5) {
                    v.performClick();
                }
                break;
        }
        return true;
    }

    private void handlePipMove(int downX, int downY, int upX, int upY) {
        int newLayoutModeValue = curLayoutMode.getValue();
        if (upX - downX > ConfConst.PIP_MOVE_MIN_DISTANCE) {
            newLayoutModeValue += 1;
        }
        if (downX - upX > ConfConst.PIP_MOVE_MIN_DISTANCE) {
            newLayoutModeValue -= 1;
        }
        if (upY - downY > ConfConst.PIP_MOVE_MIN_DISTANCE) {
            newLayoutModeValue += 2;
        }
        if (downY - upY > ConfConst.PIP_MOVE_MIN_DISTANCE) {
            newLayoutModeValue -= 2;
        }
        if (newLayoutModeValue != curLayoutMode.getValue() &&
                ConfConst.PIP_LAYOUT_MODE.contains(LayoutMode.valueOf(newLayoutModeValue))) {
            LogUtil.info("curLayoutMode = " + curLayoutMode.getValue() + " newLayoutMode = " + newLayoutModeValue);
            curLayoutMode = LayoutMode.valueOf(newLayoutModeValue);
            ConfSdkPresenter.movePipMode(curLayoutMode);

        }
    }

    public void setCurLayoutMode(LayoutMode layoutMode) {
        curLayoutMode = layoutMode;
        switch (curLayoutMode) {
            case PIP_LEFT_TOP: /* 画中画 左上 */
                layoutParams.x = ConfConst.PIP_LEFT;
                layoutParams.y = ConfConst.PIP_TOP;
                break;
            case PIP_RIGHT_TOP: /* 画中画 右上 */
                layoutParams.x = ConfConst.PIP_RIGHT;
                layoutParams.y = ConfConst.PIP_TOP;
                break;
            case PIP_LEFT_BOTTOM: /* 画中画 左下 */
                layoutParams.x = ConfConst.PIP_LEFT;
                layoutParams.y = ConfConst.PIP_BOTTOM;
                break;
            case PIP_RIGHT_BOTTOM: /* 画中画 右下 */
                layoutParams.x = ConfConst.PIP_RIGHT;
                layoutParams.y = ConfConst.PIP_BOTTOM;
                break;
        }
    }
}
